/* ***** BEGIN LICENSE BLOCK *****
 * Version: NPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Netscape Public License
 * Version 1.1 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at
 * http://www.mozilla.org/NPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is lutsko.com code.
 *
 * The Initial Developer of the Original Code is 
 * James Lutsko.
 * Portions created by the Initial Developer are Copyright (C) 2003
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the NPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the NPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

package autoschedule.ui;

import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreeSelectionModel;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;

import autoschedule.AutoScheduleDoc;
import autoschedule.ScheduleMsg;
import autoschedule.League;
import autoschedule.Facility;

import java.util.Observer;
import java.util.Observable;


public class ScheduleTree implements TreeSelectionListener, 
				     Observer
{
    DefaultMutableTreeNode top;
    DefaultMutableTreeNode facilities;
    DefaultMutableTreeNode leagues;
    DefaultMutableTreeNode schedules;
    DefaultMutableTreeNode fac_sched;
    DefaultMutableTreeNode lea_sched;
    DefaultMutableTreeNode reports;
    DefaultMutableTreeNode game_calendar;

    JTree tree;
    DefaultTreeModel treeModel = null;

    AutoScheduleDoc doc = null;

    public JTree getTree(){ return tree;}

    public ScheduleTree()
    {
	top =new DefaultMutableTreeNode("Schedule Components");

	tree = new JTree(top);
	tree.getSelectionModel().setSelectionMode
	    (TreeSelectionModel.SINGLE_TREE_SELECTION);

	treeModel = new DefaultTreeModel(top);
	tree.setModel(treeModel);
        
	createTopNodes();

        game_calendar = new DefaultMutableTreeNode("Games Calendar");
        treeModel.insertNodeInto(game_calendar, top, 4);
    }

    private void createTopNodes()
    {      
        facilities = new DefaultMutableTreeNode("Facilities");
        treeModel.insertNodeInto(facilities,top,0);

        leagues = new DefaultMutableTreeNode("Leagues");
        treeModel.insertNodeInto(leagues,top,1);

	schedules = new DefaultMutableTreeNode("Schedules");
	treeModel.insertNodeInto(schedules,top,2);
	
	fac_sched = new DefaultMutableTreeNode("Facility Schedules");
	treeModel.insertNodeInto(fac_sched,schedules,0);

	lea_sched = new DefaultMutableTreeNode("League Schedules");
	treeModel.insertNodeInto(lea_sched,schedules,1);

	reports = new DefaultMutableTreeNode("Reports");
	treeModel.insertNodeInto(reports,top,3);
    }        

    DefaultMutableTreeNode getSelectedNode()
    {
	TreePath tp = tree.getSelectionPath();
	if(tp == null) return null;

	DefaultMutableTreeNode node = (DefaultMutableTreeNode) tp.getLastPathComponent();
	return node;
    }

    Object getSelectedUserData()
    {
	DefaultMutableTreeNode node = getSelectedNode();
	if(node == null) return null;

	return node.getUserObject();
    }

    Facility getSelectedFacility()
    {
	Object uo = getSelectedUserData();
	if(uo == null) return (Facility) uo;
	if(uo instanceof Facility) return (Facility) uo;
	return null;
    }

    League getSelectedLeague()
    {
	Object uo = getSelectedUserData();
	if(uo == null) return (League) uo;
	if(uo instanceof League) return (League) uo;
	return null;
    }
    
    boolean isScheduleNode(DefaultMutableTreeNode node)
    {
	if(node == null) return false;

	return node.isNodeAncestor(schedules);
    }

    public void update(Observable o, Object _msg)
    {
	ScheduleMsg msg = (ScheduleMsg) _msg;

	System.out.println("Processing msg " +msg.getArg());
	if(msg.getArg() instanceof Facility)
	    processFacilityMsg((AutoScheduleDoc) doc, msg);
	else if(msg.getArg() instanceof League)
	    processLeagueMsg((AutoScheduleDoc) doc, msg);
	else if(msg.getArg() instanceof AutoScheduleDoc)
	    processScheduleMsg((AutoScheduleDoc) doc, msg);
    }

    public void processScheduleMsg(AutoScheduleDoc doc, ScheduleMsg msg)
    {
	if(msg.getMsg() == doc.SCHEDULE_CHANGED)
	    {
		System.out.println("Schedule changed");
		treeModel.removeNodeFromParent((DefaultMutableTreeNode) fac_sched);
		treeModel.removeNodeFromParent((DefaultMutableTreeNode) lea_sched);

		fac_sched = new DefaultMutableTreeNode("Facility Schedules");
		treeModel.insertNodeInto(fac_sched,schedules,0);

		lea_sched = new DefaultMutableTreeNode("League Schedules");
		treeModel.insertNodeInto(lea_sched,schedules,1);
		
		for(int f = 0; f< doc.getNumberOfFacilities();f++)
		    {
			Object o = doc.getFacility(f);
			DefaultMutableTreeNode fac = new DefaultMutableTreeNode(o);
			treeModel.insertNodeInto(fac, fac_sched,f);
			System.out.println("Inserted Node " + f);
		    }
		
		for(int l = 0; l< doc.getNumberOfLeagues();l++)
		    {
			League o = (League) doc.getLeague(l);
			DefaultMutableTreeNode lea = new DefaultMutableTreeNode(o);
			lea_sched.add(lea);
			for(int t = 0; t< o.getNumberOfTeams(); t++)
			    {
				DefaultMutableTreeNode n = new DefaultMutableTreeNode(o.getTeam(t));
				treeModel.insertNodeInto(n, lea,t);
			    }
		    }		
	   } 
    }
    public void processFacilityMsg(AutoScheduleDoc doc, ScheduleMsg msg)
    {
	Facility f = (Facility) msg.getArg();
	if(msg.getMsg() == doc.ADD)
	    {
		DefaultMutableTreeNode fac = new DefaultMutableTreeNode(f);
		int n = treeModel.getChildCount(facilities);
		treeModel.insertNodeInto(fac,facilities,n);
	    } else if(msg.getMsg() == doc.RENAME) {
		DefaultMutableTreeNode node = (DefaultMutableTreeNode) facilities.getFirstChild();
		while(node != null)
		    {
			if(node.getUserObject() == f)
			    {
				treeModel.nodeChanged(node);
				break;
			    }
			node = (DefaultMutableTreeNode) facilities.getChildAfter(node);
		    }
		} else if(msg.getMsg() == doc.DEL) {
		DefaultMutableTreeNode node = (DefaultMutableTreeNode) facilities.getFirstChild();
		while(node != null)
		    {
			if(node.getUserObject() == f)
			    {
				treeModel.removeNodeFromParent(node);
				break;
			    }
			node = (DefaultMutableTreeNode) facilities.getChildAfter(node);
		    }
	    }
    }
    public void processLeagueMsg(AutoScheduleDoc doc, ScheduleMsg msg)
    {
	League lg = (League) msg.getArg();
	System.out.println("Processing league " + lg);
	if(msg.getMsg() == doc.ADD)
	    {
		DefaultMutableTreeNode lnode = new DefaultMutableTreeNode(lg);
		int n = treeModel.getChildCount(leagues);
		treeModel.insertNodeInto(lnode,leagues,n);
	    } else if(msg.getMsg() == doc.RENAME) {
		DefaultMutableTreeNode node = (DefaultMutableTreeNode) leagues.getFirstChild();
		while(node != null)
		    {
			if(node.getUserObject() == lg)
			    {
				treeModel.nodeChanged(node);
				break;
			    }
			node = (DefaultMutableTreeNode) leagues.getChildAfter(node);
		    }
	    } else if(msg.getMsg() == doc.DEL) {
		System.out.println("Deleting league " + lg);
		DefaultMutableTreeNode node = (DefaultMutableTreeNode) leagues.getFirstChild();
		while(node != null)
		    {
			if(node.getUserObject() == lg)
			    {
				treeModel.removeNodeFromParent(node);
				break;
			    }
			node = (DefaultMutableTreeNode) leagues.getChildAfter(node);
		    }
	    }
    }
    public void setDoc(AutoScheduleDoc _doc)
    {
	doc = _doc;
	doc.addObserver(this);

	treeModel.removeNodeFromParent((DefaultMutableTreeNode) facilities);
	treeModel.removeNodeFromParent((DefaultMutableTreeNode) leagues);
	treeModel.removeNodeFromParent((DefaultMutableTreeNode) schedules);
	treeModel.removeNodeFromParent((DefaultMutableTreeNode) reports);
	createTopNodes();
	   

	for(int f = 0; f< doc.getNumberOfFacilities();f++)
	    {
		Object o = doc.getFacility(f);
		DefaultMutableTreeNode fac = new DefaultMutableTreeNode(o);
		facilities.add(fac);
	    }

	for(int l = 0; l< doc.getNumberOfLeagues();l++)
	    {
		League o = (League) doc.getLeague(l);
		DefaultMutableTreeNode lea = new DefaultMutableTreeNode(o);
		leagues.add(lea);
		/*
		  for(int t = 0; t< o.getNumberOfTeams(); t++)
		  {
		  DefaultMutableTreeNode n = new DefaultMutableTreeNode(o.getTeam(t));
		  lea.add(n);
		  }*/
	    }
	tree.expandPath(tree.getPathForRow(0));
    }
  public void valueChanged(TreeSelectionEvent e) {
        DefaultMutableTreeNode node = (DefaultMutableTreeNode)
                           tree.getLastSelectedPathComponent();

        if (node == null) return;

        Object nodeInfo = node.getUserObject();
        if (node.isLeaf()) {
	    //            BookInfo book = (BookInfo)nodeInfo;
	    //            displayURL(book.bookURL);
	    //            if (DEBUG) {
	    //                System.out.print(book.bookURL + ":  \n    ");
	    //            }
        } else {
	    //            displayURL(helpURL); 
        }
	//        if (DEBUG) {
	//            System.out.println(nodeInfo.toString());
	//        }
    }

}
